import Block from './block.js'
import Direction from './direction.js'
import EnemyTank from './enemytank.js'
import config from './gameconfig.js'
import Grass from './grass.js'
import PlayerTank from './playertank.js'
import Wall from './wall.js'
import Water from './water.js'

class Game {
  moveKeys: Array<string> = new Array<string>()
  mapData: Array<Block>
  context: CanvasRenderingContext2D | null
  playerTank: PlayerTank;
  waters:Array<Water> = new Array<Water>();
  enemies:Array<EnemyTank> = new Array<EnemyTank>();
  // cols : Array<Block> = new Array<Block>();
  constructor(context: CanvasRenderingContext2D | null) {
    this.context = context
    this.mapData = new Array<Block>()
    this.playerTank = new PlayerTank(0, 0)
  }
  start(): void {
    this.initMap()
    setInterval(() => {
      this.update()
      this.render()
    }, config.GameInterval)
    this.bindKey()
  }
  update() {
    let walls = this.mapData.filter(e=>e instanceof Wall);
    this.updatePlayer(new Array<Block>().concat(this.waters,walls,this.enemies))
  }
  updatePlayer(cols:Array<Block>) {
    if (this.moveKeys.length > 0) {
      let dir = this.moveKeys[0]
      switch (dir) {
        case config.DirectionKey.TOP:
          this.playerTank.direction = Direction.TOP
          break
        case config.DirectionKey.RIGHT:
          this.playerTank.direction = Direction.RIGHT
          break
        case config.DirectionKey.DOWN:
          this.playerTank.direction = Direction.BOTTOM
          break
        case config.DirectionKey.LEFT:
          this.playerTank.direction = Direction.LEFT
          break
      }
      this.playerTank.controlMove(cols)
    }
  }
  render() {
    this.renderMap()
    this.renderTank()
  }
  renderTank() {
    this.playerTank.render(this.context);
  }
  renderMap() {
    this.mapData.forEach(e => e.render(this.context))
  }

  gui(): void {}

  initMap(): void {
    let row = Math.floor(config.MapMaxWidth / config.BlockSize)
    let col = Math.floor(config.MapMaxHeight / config.BlockSize)
    for (let i = 0; i < row; i++) {
      for (let j = 0; j < col; j++) {
        var r = Math.random() * 100
        let x = i * config.BlockSize
        let y = j * config.BlockSize
        if (r <= 75) {
          this.mapData.push(new Grass(x, y))
        } else if (r <= 90) {
          this.mapData.push(new Wall(x, y))
        } else {
          let w = new Water(x, y);
          this.mapData.push(w)
          this.waters.push(w);
        }
      }
    }
    config.EnemySpawns.forEach(e => {
      let x = this.mapData[e].x
      let y = this.mapData[e].y
      this.mapData[e] = new Grass(x, y)
    })

    let x = this.mapData[config.PlayerSpawn].x
    let y = this.mapData[config.PlayerSpawn].y
    this.mapData[config.PlayerSpawn] = new Grass(x, y)
    this.playerTank.x = x
    this.playerTank.y = y
  }

  bindKey(): void {
    document.addEventListener('keydown', e => {
      if (Object.values(config.DirectionKey).includes(e.code)) {
        if (!this.moveKeys.includes(e.code)) {
          this.moveKeys.unshift(e.code)
        }
      }
    })
    document.addEventListener('keyup', e => {
      if (Object.values(config.DirectionKey).includes(e.code)) {
        let index = this.moveKeys.indexOf(e.code)
        if (index != -1) {
          this.moveKeys.splice(index, 1)
        }
      }
    })
  }
}
export default Game
